#include "morphology_plugin.h"

#include "ui_plugin.h"

Morphology_Plugin::Morphology_Plugin()
{
    // Insert initialization codes here ...
}

Morphology_Plugin::~Morphology_Plugin()
{
    // Insert cleanup codes here ...
}

QString Morphology_Plugin::title()
{
    return this->metaObject()->className();
}

QString Morphology_Plugin::version()
{
    return "1.0.0";
}

QString Morphology_Plugin::description()
{
    return "Performs different filters available in OpenCV";
}

QString Morphology_Plugin::help()
{
    return "This is a plugin that performs different filters available in OpenCV";
}

void Morphology_Plugin::setupUi(QWidget *parent)
{
    ui = new Ui::PluginGui;
    ui->setupUi(parent);

    ui->morphShapesCombo->addItems(
                QStringList() << "MORPH_RECT" << "MORPH_CROSS" << "MORPH_ELLIPSE");
    ui->morphTypesCombo->addItems(
                QStringList() << "MORPH_ERODE" << "MORPH_DILATE" << "MORPH_OPEN" << "MORPH_CLOSE"
                << "MORPH_GRADIENT" << "MORPH_TOPHAT" << "MORPH_BLACKHAT");
    ui->morphTypesCombo->setEnabled(false);

    connect(ui->DilateRadio, SIGNAL(toggled(bool)), this, SLOT(on_DilateRadio_toggled(bool)));
    connect(ui->ErodeRadio, SIGNAL(toggled(bool)), this, SLOT(on_ErodeRadio_toggled(bool)));
    connect(ui->MorphRadio, SIGNAL(toggled(bool)), this, SLOT(on_MorphRadio_toggled(bool)));
    connect(ui->IterSpin, SIGNAL(valueChanged(int)), this, SLOT(on_IterSpin_valueChanged(int)));
    connect(ui->ksizeWspinBox, SIGNAL(valueChanged(int)), this, SLOT(on_ksizeWspinBox_valueChanged(int)));
    connect(ui->ksizeHspinBox, SIGNAL(valueChanged(int)), this, SLOT(on_ksizeHspinBox_valueChanged(int)));
    connect(ui->morphShapesCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(on_morphShapesCombo_currentIndexChanged(int)));
    connect(ui->morphTypesCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(on_morphTypesCombo_currentIndexChanged(int)));
    connect(ui->urllabel1,SIGNAL(linkActivated(QString)),this,SLOT(openURL(QString)));
    connect(ui->urllabel2,SIGNAL(linkActivated(QString)),this,SLOT(openURL(QString)));
}

void Morphology_Plugin::processImage(const cv::Mat &inputImage, cv::Mat &outputImage)
{
    using namespace cv;

    if(ui->ErodeRadio->isChecked())
    {
        erode(inputImage,
              outputImage,
              getStructuringElement(ui->morphShapesCombo->currentIndex(),
                                    Size(ui->ksizeWspinBox->value(),
                                         ui->ksizeHspinBox->value())),
              Point(-1,-1),
              ui->IterSpin->value());
    }
    else if(ui->DilateRadio->isChecked())
    {
        dilate(inputImage,
               outputImage,
               getStructuringElement(ui->morphShapesCombo->currentIndex(),
                                     Size(ui->ksizeWspinBox->value(),
                                          ui->ksizeHspinBox->value())),
               Point(-1,-1),
               ui->IterSpin->value());
    }
    else if(ui->MorphRadio->isChecked())
    {
        morphologyEx(inputImage,
                     outputImage,
                     ui->morphTypesCombo->currentIndex(),
                     getStructuringElement(ui->morphShapesCombo->currentIndex(),
                                           Size(ui->ksizeWspinBox->value(),
                                                ui->ksizeHspinBox->value())),
                     Point(-1,-1),
                     ui->IterSpin->value());
    }

}

void Morphology_Plugin::openURL(QString url)
{
    QDesktopServices::openUrl(url);
}

void Morphology_Plugin::on_ErodeRadio_toggled(bool checked)
{
    Q_UNUSED(checked);
    QString s(tr("C++ API:<br>"
              "void cv::erode ( InputArray  src,<br>"
              "OutputArray  dst,<br>"
              "InputArray  kernel"
              "Point anchor = Point(-1,-1),<br>"
              "int  iterations = 1,<br>"
              "int borderType = BORDER_CONSTANT,<br>"
              "const Scalar& borderValue = morphologyDefaultBoederValue())<br>"
              "Python:<br>"
              "dst = cv.erode ( <br>"
              "src, kernel[, dst[, anchor[, iterations[, borderType[, boederValue]]]]])"));

    ui->textEdit->setText(s);
    ui->ksizeWspinBox->setValue(1);
    ui->ksizeHspinBox->setValue(1);
    ui->IterSpin->setValue(1);
    emit updateNeeded();
}

void Morphology_Plugin::on_DilateRadio_toggled(bool checked)
{
    Q_UNUSED(checked);
    QString s("C++ API:<br>"
              "void cv::dilate ( InputArray  src,<br>"
              "OutputArray  dst,<br>"
              "InputArray  kernel"
              "Point anchor = Point(-1,-1),<br>"
              "<tab>int  iterations = 1,<br>"
              "int borderType = BORDER_CONSTANT,"
              "const Scalar& borderValue = morphologyDefaultBoederValue())<br>"
              "Python:<br>"
              "dst = cv.dilate ( <br>"
              "src, kernel[, dst[, anchor[, iterations[, borderType[, boederValue]]]]])");

    ui->textEdit->setText(s);
    ui->ksizeWspinBox->setValue(1);
    ui->ksizeHspinBox->setValue(1);
    ui->IterSpin->setValue(1);
    emit updateNeeded();
}

void Morphology_Plugin::on_MorphRadio_toggled(bool checked)
{
    Q_UNUSED(checked);
    QString s("C++ API:<br>"
              "void cv::morphologyEx ( InputArray  src,<br>"
              "OutputArray  dst,<br>"
              "int  op,<br>"
              "InputArry    kernel,<br>"
              "Point anchor = Point(-1,-1),<br>"
              "<tab>int  iterations = 1,<br>"
              "<tab>int borderType = BORDER_CONSTANT,"
              "<tab>const Scalar& borderValue = morphologyDefaultBoederValue())<br>"
              "Python:<br>"
              "dst = cv.morphologyEx ( <br>"
              "src, op, kernel[, dst[, anchor[, iterations[, borderType[, boederValue]]]]])");

    ui->textEdit->setText(s);
    ui->ksizeWspinBox->setValue(1);
    ui->ksizeHspinBox->setValue(1);
    ui->IterSpin->setValue(1);
    ui->morphTypesCombo->setEnabled(true);
    emit updateNeeded();
}

void Morphology_Plugin::on_morphTypesCombo_currentIndexChanged(int index)
{
    Q_UNUSED(index);
    emit updateNeeded();
}

void Morphology_Plugin::on_ksizeHspinBox_valueChanged(int arg1)
{
    Q_UNUSED(arg1);
    emit updateNeeded();
}

void Morphology_Plugin::on_ksizeWspinBox_valueChanged(int arg1)
{
    Q_UNUSED(arg1);
    emit updateNeeded();
}

void Morphology_Plugin::on_IterSpin_valueChanged(int arg1)
{
    Q_UNUSED(arg1);
    emit updateNeeded();
}

void Morphology_Plugin::on_morphShapesCombo_currentIndexChanged(int index)
{
    Q_UNUSED(index);
    emit updateNeeded();
}
